﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
using OrionApplication.OrionLib.Orion;
using OrionApplication.OrionLib.Dao;

namespace OrionApplication.OrionForm
{
    public partial class OrionBaseForm
        : ComponentFactory.Krypton.Toolkit.KryptonForm,
        OrionApplication.OrionForm.Base.Interface.OrionBaseFormInterface
    {
        /// <summary>
        /// Nom du formulaire qui a été ouvert
        /// </summary>
        public string NameFormA = string.Empty;
        /// <summary>
        /// Indique au programme si les événements ont déjà étaient mis en place
        /// </summary>
        protected bool IsEvenFiredBase = false;
        /// <summary>
        /// Chaine de caractère qui sera mis dans le titre de la fenêtre
        /// </summary>
        public string Titre = string.Empty;

        #region Constructeur
        public OrionBaseForm()
        {
            InitializeComponent();
        }

        public OrionBaseForm(string titre)
        {
            this.Titre = titre;
            InitializeComponent();
        }
        #endregion

        #region Evenements Génériques
        private void kTb_Leave(object sender, EventArgs e)
        {
            this.ParseLanceAction((Control)sender, "ONLEAVE");
        }

        private void kTb_Enter(object sender, EventArgs e)
        {
            this.ParseLanceAction((Control)sender, "ONENTER");
        }

        private void kDg_RowEnter(object sender, DataGridViewCellEventArgs e)
        {
            this.ParseLanceAction((Control)sender, "ONROWENTER");
        }

        private void kBtn_Click(object sender, EventArgs e)
        {
            this.ParseLanceAction((Control)sender, "ONCLICK");
        }

        private void OrionBaseForm_Load(object sender, EventArgs e)
        {
            this.Text = this.Titre;
        }

        private void OrionBaseForm_Activated(object sender, EventArgs e)
        {
            if (!this.IsEvenFiredBase)
            {
                this.SetEvenFormOnOpenForm();
                this.SetEvenToControls();
                this.IsEvenFiredBase = true;
            }
        }
        #endregion

        /// <summary>
        /// Lance les actions paramétrées en base pour le contrôle et type d'enevement mise en paramétre
        /// </summary>
        /// <param name="Sender">Le contrôle qui a généré l'événement</param>
        /// <param name="TypEven">Le type d'événement</param>
        public void ParseLanceAction(Control Sender, String TypEven)
        {
            DaoOrionEven daoE = new DaoOrionEven();
            string quoi = daoE.GetQuoi(this.NameFormA, Sender.Name, TypEven);
            if (quoi != string.Empty)
            {
                this.ParseEtLanceQuoi(quoi);
            }
        }

        /// <summary>
        /// Parse et lance les actions associés à un événement.
        /// </summary>
        /// <param name="quoi"></param>
        public void ParseEtLanceQuoi(string quoi)
        {
            String[] tabAction = quoi.Split('|');
            foreach (string action in tabAction)
            {
                try
                {
                    // C'est une fonction interne à OrionBaseForm ou une de ses filles
                    if (action.StartsWith("$"))
                    {
                        string[] tabFonctionParam = action.TrimStart('$').Split(',');
                        string nameFonction = tabFonctionParam[0];
                        if (nameFonction.Equals("RempliCbOrionTable"))
                        {
                            // Nous récupérons le Composant du formulaire
                            Control c = OrionOutils.GetControlsAvecRecursivite(this, tabFonctionParam[1]);
                            object[] tabParam = new object[tabFonctionParam.Count() - 1];
                            tabParam[0] = c;
                            for (int i = 2; i < tabFonctionParam.Count(); i++)
                                tabParam[i - 1] = tabFonctionParam[i];

                            this.GetType().InvokeMember(nameFonction, BindingFlags.Default |
                                        BindingFlags.Public | BindingFlags.NonPublic |
                                        BindingFlags.Instance | BindingFlags.InvokeMethod,
                                        null, this, tabParam);
                        }
                        else
                        {
                            //C'est une fonction sans paramétre
                            if (tabFonctionParam.Count() == 1)
                            {
                                this.GetType().InvokeMember(nameFonction, BindingFlags.Default |
                                        BindingFlags.Public | BindingFlags.NonPublic |
                                        BindingFlags.Instance | BindingFlags.InvokeMethod,
                                        null, this, null);
                            }
                            // C'est une fonction avec paramétre
                            else
                            {
                                string[] tabParam = new string[tabFonctionParam.Count() - 1];

                                for (int i = 1; i < tabFonctionParam.Count(); i++)
                                    tabParam[i - 1] = tabFonctionParam[i];

                                this.GetType().InvokeMember(nameFonction, BindingFlags.Default |
                                        BindingFlags.Public | BindingFlags.NonPublic |
                                        BindingFlags.Instance | BindingFlags.InvokeMethod,
                                        null, this, tabParam);
                            }
                        }
                    }
                    // C'est une affectation de valeur à un champ
                    else if (action.StartsWith("@"))
                    {
                        string[] tabChampValeur = action.TrimStart('@').Split(',');
                        if (tabChampValeur.Count() == 3)
                        {
                            // Nous récupérons le Composant du formulaire
                            Control c = OrionOutils.GetControlsAvecRecursivite(this, tabChampValeur[0]);
                            object[] val;
                            // Selon la propriété, ce sont des conversions différentes
                            // BOOLEAN
                            if (tabChampValeur[1].Equals("Checked"))
                            {
                                val = new object[1]; val[0] = Convert.ToBoolean(tabChampValeur[2]);
                                if (c.GetType().ToString().Equals("ComponentFactory.Krypton.Toolkit.KryptonDateTimePicker"))
                                {
                                    c.GetType().InvokeMember(tabChampValeur[1], BindingFlags.SetProperty, null, c, val);
                                }
                                else
                                {
                                    throw new Exception("Attention le paramétrage suivant n'est pas pris en compte dans le noyau : "
                                                            + Environment.NewLine
                                                            + action);
                                }
                            }
                            // OBJECT
                            else if (tabChampValeur[1].Equals("Value"))
                            {
                                // Celon l'objet, la "Value" est un :
                                // DATETIME
                                if (c.GetType().ToString().Equals("ComponentFactory.Krypton.Toolkit.KryptonDateTimePicker"))
                                {
                                    val = new object[1]; val[0] = Convert.ToDateTime(tabChampValeur[2]);
                                    c.GetType().InvokeMember(tabChampValeur[1], BindingFlags.SetProperty, null, c, val);
                                }
                                // DECIMAL
                                else if (c.GetType().ToString().Equals("ComponentFactory.Krypton.Toolkit.KryptonNumericUpDown"))
                                {
                                    val = new object[1]; val[0] = Convert.ToDecimal(tabChampValeur[2]);
                                    c.GetType().InvokeMember(tabChampValeur[1], BindingFlags.SetProperty, null, c, val);
                                }
                                else
                                {
                                    throw new Exception("Attention le paramétrage suivant n'est pas pris en compte dans le noyau : "
                                                            + Environment.NewLine
                                                            + action);
                                }
                            }
                            // OBJECT
                            else if (tabChampValeur[1].Equals("SelectedValue"))
                            {
                                // Celon l'objet, la "SelectedValue" est un :
                                // INTEGER
                                if (c.GetType().ToString().Equals("ComponentFactory.Krypton.Toolkit.KryptonComboBox"))
                                {
                                    val = new object[1]; val[0] = Convert.ToInt32(tabChampValeur[2]);
                                    c.GetType().InvokeMember(tabChampValeur[1], BindingFlags.SetProperty, null, c, val);
                                }
                                else
                                {
                                    throw new Exception("Attention le paramétrage suivant n'est pas pris en compte dans le noyau : "
                                                            + Environment.NewLine
                                                            + action);
                                }
                            }
                            else
                            {
                                val = new object[1]; val[0] = tabChampValeur[2];
                                c.GetType().InvokeMember(tabChampValeur[1], BindingFlags.SetProperty, null, c, val);
                            }
                        }
                        /*else if (action.StartsWith("#"))
                        { }*/
                        /*else if (action.StartsWith("£"))
                        { }*/
                        /*else if (action.StartsWith("µ"))
                        { }*/
                        else
                        {
                            throw new Exception("Attention le paramétrage suivant n'est pas pris en compte dans le noyau : "
                                                            + Environment.NewLine
                                                            + action);
                        }
                    }
                }
                catch (Exception ex)
                {
                    OrionOutils.Erreur("Erreur dans le Parseur du paramétrage des événements", ex.Message + Environment.NewLine + Environment.NewLine + action);
                }
            }
        }

        /// <summary>
        /// Lance les événements sur l'ouverture du formulaire.
        /// Evenement "ONOPENFORM"
        /// </summary>
        public void SetEvenFormOnOpenForm()
        {
            DaoOrionEven daoE = new DaoOrionEven();
            string quoi = daoE.GetQuoi(this.NameFormA, "ONOPENFORM");
            if (quoi != string.Empty)
            {
                this.ParseEtLanceQuoi(quoi);
            }
        }

        /// <summary>
        /// Nous attachons les événements 'Générique' paramétrés aux différents contrôles du formulaire
        /// </summary>
        public void SetEvenToControls()
        {
            // Nous obtenons une liste de tous les contrôles du formulaire
            IEnumerable<Control> controls = OrionOutils.ControlsAvecRecursivite(this);
            // Pour chaque contrôle
            foreach (Control c in controls)
            {
                // Si c'est une textbox
                if (c.GetType().ToString().Equals("ComponentFactory.Krypton.Toolkit.KryptonTextBox"))
                {
                    // Nous ajoutons l'événement à l'entrée et sortie du champ
                    c.Leave += new System.EventHandler(this.kTb_Leave);
                    c.Enter += new System.EventHandler(this.kTb_Enter);
                }
                // Si c'est un bouton
                else if (c.GetType().ToString().Equals("ComponentFactory.Krypton.Toolkit.KryptonButton"))
                {
                    // Nous ajoutons l'événement au clique
                    c.Click += new System.EventHandler(this.kBtn_Click);
                }
                // Si c'est le DataGrid
                else if (c.GetType().ToString().Equals("ComponentFactory.Krypton.Toolkit.KryptonDataGridView"))
                {
                    // Nous ajoutons l'événement lorsque le curseur entre dans une ligne
                    ((ComponentFactory.Krypton.Toolkit.KryptonDataGridView)c).RowEnter += new System.Windows.Forms.DataGridViewCellEventHandler(kDg_RowEnter);
                }
                else if (c.GetType().ToString().Equals("OrionApplication.OrionForm.Composant.OrionComboTable"))
                {
                    c.GetType().InvokeMember("RempliCb", BindingFlags.Default |
                                       BindingFlags.Public | BindingFlags.NonPublic |
                                       BindingFlags.Instance | BindingFlags.InvokeMethod,
                                       null, c, null);
                }
            }
        }

        /// <summary>
        /// Permet de spécifier la form Parente
        /// </summary>
        /// <param name="FormParent">La forme parente à assigner</param>
        public void SetMdiParent(Form FormParent)
        {
            this.MdiParent = FormParent;
        }

        /// <summary>
        /// Permet de spécifier le NameForm qui sera utilisé pour les Evenements
        /// </summary>
        /// <param name="NameFormP">Le NameForm à utiliser</param>
        public void SetNameForm(String NameFormP)
        {
            this.NameFormA = NameFormP;
        }

        /// <summary>
        /// Permet de remplir une KryptonCombobox avec un identifiant OrionTable
        /// </summary>
        /// <param name="cb">KryptonCombobox à remplir</param>
        /// <param name="displayMember">Le display member de la Combobox</param>
        /// <param name="valueMember">Le value member de la Combobox</param>
        /// <param name="ident">L'identifion OrionTable servant à remplir la Combobox</param>
        public void RempliCbOrionTable(ComponentFactory.Krypton.Toolkit.KryptonComboBox cb, String displayMember, String valueMember, String ident)
        {
            DaoOrionTable daoT = new DaoOrionTable();
            cb.DisplayMember = displayMember;
            cb.ValueMember = valueMember;
            cb.DataSource = daoT.SelectByIdent(ident, true);
        }

        /// <summary>
        /// Permet de mettre à blanc tout un formulaire
        /// </summary>
        public void VideFormulaire()
        {
            // Nous obtenons une liste de tous les contrôles du formulaire
            IEnumerable<Control> controls = OrionOutils.ControlsAvecRecursivite(this);
            // Pour chaque contrôle
            foreach (Control c in controls)
            {
                // Si c'est une textbox
                if (c.GetType().ToString().Equals("ComponentFactory.Krypton.Toolkit.KryptonTextBox"))
                {
                    ((ComponentFactory.Krypton.Toolkit.KryptonTextBox)c).Text = string.Empty;
                }
                else if (c.GetType().ToString().Equals("ComponentFactory.Krypton.Toolkit.KryptonComboBox"))
                {
                    ((ComponentFactory.Krypton.Toolkit.KryptonComboBox)c).SelectedValue = 0;
                }
                else if (c.GetType().ToString().Equals("OrionApplication.OrionForm.Composant.OrionComboTable"))
                {
                    ((OrionApplication.OrionForm.Composant.OrionComboTable)c).Cb.SelectedValue = 0;
                }
                else if (c.GetType().ToString().Equals("ComponentFactory.Krypton.Toolkit.KryptonDateTimePicker"))
                {
                    ((ComponentFactory.Krypton.Toolkit.KryptonDateTimePicker)c).Checked = false;
                }
                else if (c.GetType().ToString().Equals("ComponentFactory.Krypton.Toolkit.KryptonNumericUpDown"))
                {
                    ((ComponentFactory.Krypton.Toolkit.KryptonNumericUpDown)c).Value = Convert.ToDecimal(0.0);
                }
            }
        }
    }
}
